"""
任务实体模型
"""

from sqlalchemy import (
    Column, String, Text, Integer, Float, Boolean, 
    JSON, ForeignKey, Enum as SQLEnum, DateTime
)
from sqlalchemy.orm import relationship, declarative_base
from datetime import datetime
from enum import Enum
import uuid

from ..core.database import Base


class TaskStatus(Enum):
    """任务状态"""
    PENDING = "pending"          # 待处理
    RUNNING = "running"          # 运行中
    COMPLETED = "completed"      # 已完成
    FAILED = "failed"            # 失败
    CANCELLED = "cancelled"      # 已取消
    TIMEOUT = "timeout"          # 超时


class TaskPriority(Enum):
    """任务优先级"""
    LOW = "low"
    NORMAL = "normal"
    HIGH = "high"
    URGENT = "urgent"


class TaskType(Enum):
    """任务类型"""
    AUDIOBOOK_GENERATION = "audiobook_generation"    # 有声读物生成
    VIDEO_DUBBING = "video_dubbing"                  # 视频配音
    AUDIO_CONVERSION = "audio_conversion"            # 音频转换
    BATCH_TTS = "batch_tts"                          # 批量TTS
    AUDIO_ENHANCEMENT = "audio_enhancement"          # 音频增强
    CLEANUP = "cleanup"                               # 清理任务
    BACKUP = "backup"                                 # 备份任务
    CUSTOM = "custom"                                 # 自定义任务


class Task(Base):
    """任务模型"""
    __tablename__ = "tasks"
    
    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # 任务基本信息
    title = Column(String(200), nullable=False)
    description = Column(Text, nullable=True)
    task_type = Column(SQLEnum(TaskType), nullable=False, index=True)
    status = Column(SQLEnum(TaskStatus), default=TaskStatus.PENDING, index=True)
    priority = Column(SQLEnum(TaskPriority), default=TaskPriority.NORMAL, index=True)
    
    # 任务参数
    parameters = Column(JSON, nullable=False)               # 任务参数
    result = Column(JSON, nullable=True)                    # 任务结果
    error_message = Column(Text, nullable=True)             # 错误信息
    
    # 进度信息
    progress = Column(Float, default=0.0)                    # 进度 0-1
    total_steps = Column(Integer, default=0)                # 总步骤数
    current_step = Column(Integer, default=0)              # 当前步骤
    
    # 资源关联
    audiobook_id = Column(String, ForeignKey("audiobooks.id"), nullable=True, index=True)
    video_path = Column(String(500), nullable=True)        # 视频文件路径
    
    # 调度和执行
    queue_name = Column(String(50), default="default")      # 队列名称
    worker_id = Column(String(100), nullable=True)          # 执行器ID
    retry_count = Column(Integer, default=0)                 # 重试次数
    max_retries = Column(Integer, default=3)                # 最大重试次数
    
    # 时间信息
    scheduled_at = Column(DateTime, nullable=True)           # 计划执行时间
    started_at = Column(DateTime, nullable=True)              # 开始时间
    completed_at = Column(DateTime, nullable=True)           # 完成时间
    timeout_at = Column(DateTime, nullable=True)             # 超时时间
    
    # 时间戳
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # 用户关联
    user_id = Column(String, nullable=False, index=True)
    
    # 关系
    logs = relationship("TaskLog", back_populates="task", cascade="all, delete-orphan")
    
    def __repr__(self):
        return f"<Task(id='{self.id}', type='{self.task_type.value}', status='{self.status.value}')>"
    
    def to_dict(self):
        """转换为字典"""
        return {
            "id": self.id,
            "title": self.title,
            "description": self.description,
            "task_type": self.task_type.value,
            "status": self.status.value,
            "priority": self.priority.value,
            "parameters": self.parameters,
            "result": self.result,
            "error_message": self.error_message,
            "progress": self.progress,
            "total_steps": self.total_steps,
            "current_step": self.current_step,
            "audiobook_id": self.audiobook_id,
            "video_path": self.video_path,
            "queue_name": self.queue_name,
            "worker_id": self.worker_id,
            "retry_count": self.retry_count,
            "max_retries": self.max_retries,
            "scheduled_at": self.scheduled_at.isoformat() if self.scheduled_at else None,
            "started_at": self.started_at.isoformat() if self.started_at else None,
            "completed_at": self.completed_at.isoformat() if self.completed_at else None,
            "timeout_at": self.timeout_at.isoformat() if self.timeout_at else None,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "user_id": self.user_id
        }


class TaskLog(Base):
    """任务日志模型"""
    __tablename__ = "task_logs"
    
    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    task_id = Column(String, ForeignKey("tasks.id"), nullable=False, index=True)
    
    # 日志信息
    level = Column(String(10), nullable=False, index=True)    # DEBUG, INFO, WARNING, ERROR, CRITICAL
    message = Column(Text, nullable=False)
    step = Column(Integer, nullable=True)                      # 步骤号
    
    # 日志数据
    data = Column(JSON, nullable=True)                        # 附加数据
    
    # 执行信息
    function_name = Column(String(100), nullable=True)        # 函数名
    file_name = Column(String(200), nullable=True)           # 文件名
    line_number = Column(Integer, nullable=True)             # 行号
    
    # 时间戳
    timestamp = Column(DateTime, default=datetime.utcnow, nullable=False, index=True)
    
    # 关系
    task = relationship("Task", back_populates="logs")
    
    def __repr__(self):
        return f"<TaskLog(id='{self.id}', task_id='{self.task_id}', level='{self.level}')>"
    
    def to_dict(self):
        """转换为字典"""
        return {
            "id": self.id,
            "task_id": self.task_id,
            "level": self.level,
            "message": self.message,
            "step": self.step,
            "data": self.data,
            "function_name": self.function_name,
            "file_name": self.file_name,
            "line_number": self.line_number,
            "timestamp": self.timestamp.isoformat() if self.timestamp else None
        }


class TaskSchedule(Base):
    """任务调度模型"""
    __tablename__ = "task_schedules"
    
    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # 调度信息
    name = Column(String(100), nullable=False, unique=True, index=True)
    description = Column(Text, nullable=True)
    
    # 调度配置
    cron_expression = Column(String(100), nullable=False)     # Cron表达式
    task_type = Column(SQLEnum(TaskType), nullable=False)       # 任务类型
    parameters = Column(JSON, nullable=False)                   # 任务参数
    priority = Column(SQLEnum(TaskPriority), default=TaskPriority.NORMAL)
    
    # 调度状态
    is_active = Column(Boolean, default=True)
    max_concurrent = Column(Integer, default=1)                 # 最大并发数
    timeout_seconds = Column(Integer, default=3600)            # 超时时间
    
    # 执行统计
    total_runs = Column(Integer, default=0)
    successful_runs = Column(Integer, default=0)
    failed_runs = Column(Integer, default=0)
    last_run_at = Column(DateTime, nullable=True)
    next_run_at = Column(DateTime, nullable=True)
    
    # 用户关联
    user_id = Column(String, nullable=False, index=True)
    
    # 时间戳
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    def __repr__(self):
        return f"<TaskSchedule(id='{self.id}', name='{self.name}', active={self.is_active})>"
    
    def to_dict(self):
        """转换为字典"""
        return {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "cron_expression": self.cron_expression,
            "task_type": self.task_type.value,
            "parameters": self.parameters,
            "priority": self.priority.value,
            "is_active": self.is_active,
            "max_concurrent": self.max_concurrent,
            "timeout_seconds": self.timeout_seconds,
            "total_runs": self.total_runs,
            "successful_runs": self.successful_runs,
            "failed_runs": self.failed_runs,
            "last_run_at": self.last_run_at.isoformat() if self.last_run_at else None,
            "next_run_at": self.next_run_at.isoformat() if self.next_run_at else None,
            "user_id": self.user_id,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None
        }


class TaskQueue(Base):
    """任务队列模型"""
    __tablename__ = "task_queues"
    
    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # 队列信息
    name = Column(String(50), nullable=False, unique=True, index=True)
    description = Column(Text, nullable=True)
    
    # 队列配置
    max_workers = Column(Integer, default=1)                  # 最大工作进程数
    max_tasks = Column(Integer, default=100)                  # 最大任务数
    task_timeout = Column(Integer, default=3600)              # 任务超时时间
    
    # 队列状态
    is_active = Column(Boolean, default=True)
    worker_count = Column(Integer, default=0)                 # 当前工作进程数
    pending_count = Column(Integer, default=0)                 # 待处理任务数
    running_count = Column(Integer, default=0)                 # 运行中任务数
    
    # 队列统计
    total_processed = Column(Integer, default=0)
    total_failed = Column(Integer, default=0)
    total_timeout = Column(Integer, default=0)
    
    # 时间戳
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    last_activity_at = Column(DateTime, default=datetime.utcnow)
    
    def __repr__(self):
        return f"<TaskQueue(id='{self.id}', name='{self.name}', active={self.is_active})>"
    
    def to_dict(self):
        """转换为字典"""
        return {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "max_workers": self.max_workers,
            "max_tasks": self.max_tasks,
            "task_timeout": self.task_timeout,
            "is_active": self.is_active,
            "worker_count": self.worker_count,
            "pending_count": self.pending_count,
            "running_count": self.running_count,
            "total_processed": self.total_processed,
            "total_failed": self.total_failed,
            "total_timeout": self.total_timeout,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
            "last_activity_at": self.last_activity_at.isoformat() if self.last_activity_at else None
        }


class TaskDependency(Base):
    """任务依赖模型"""
    __tablename__ = "task_dependencies"
    
    id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
    
    # 依赖关系
    parent_task_id = Column(String, ForeignKey("tasks.id"), nullable=False, index=True)
    child_task_id = Column(String, ForeignKey("tasks.id"), nullable=False, index=True)
    
    # 依赖类型
    dependency_type = Column(String(20), default="success")   # success, completion, failure
    is_required = Column(Boolean, default=True)               # 是否必需
    
    # 时间戳
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    def __repr__(self):
        return f"<TaskDependency(parent='{self.parent_task_id}', child='{self.child_task_id}')>"
    
    def to_dict(self):
        """转换为字典"""
        return {
            "id": self.id,
            "parent_task_id": self.parent_task_id,
            "child_task_id": self.child_task_id,
            "dependency_type": self.dependency_type,
            "is_required": self.is_required,
            "created_at": self.created_at.isoformat() if self.created_at else None
        }
